from datetime import datetime

from manger import scheduler
from flask import Blueprint
from views import kpl_tool
from dao.seleted_stock import SeletedStock
from dao.candidate_stock import  CandidateStock
from manger import db
from concurrent.futures import ThreadPoolExecutor
import concurrent.futures
from views import notice_tool
from dao import PositonStock,PositonStockSchema
from sqlalchemy import and_

position = Blueprint('position', __name__)

# 增加持仓股票
@position.route('/add/<code>')
def add(code):
    if len(code) != 6:
        return {'code': 0, 'message': "参数不对"}
    candidate_stock = CandidateStock.query.filter(CandidateStock.Code == code).first()
    positonStock = PositonStock.query.filter(PositonStock.code == code).first()
    if positonStock is None:
        positonStock = PositonStock()
    defensive, last_px = kpl_tool.get_defensive_data(code)

    if candidate_stock is not None:
        positonStock.ID = candidate_stock.ID
        positonStock.code = candidate_stock.Code
        positonStock.creatTime = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
        positonStock.diff = candidate_stock.Diff
        if last_px > 0:
            positonStock.diff = (last_px - candidate_stock.NowCost30) / candidate_stock.NowCost30 * 100

        positonStock.name = candidate_stock.Name
        positonStock.nowCost15 = candidate_stock.NowCost15
        positonStock.nowCost30 = candidate_stock.NowCost30
        positonStock.score = candidate_stock.Score
        positonStock.Topics = candidate_stock.Topics
        positonStock.TopicsHot = candidate_stock.TopicsHot
        positonStock.kplTopics = candidate_stock.kplTopics
        positonStock.isSelected = candidate_stock.isSelected
        positonStock.defensive15 = candidate_stock.NowCost30
        positonStock.defensive30 = defensive
    else:
        seletedStock = SeletedStock.query.filter(SeletedStock.code == code).first()
        if seletedStock is not None:
            positonStock.ID = seletedStock.id
            positonStock.code = seletedStock.code
            positonStock.creatTime = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
            if last_px > 0:
                positonStock.diff = (last_px - seletedStock.CostLine30) / seletedStock.CostLine30 * 100
            positonStock.name = seletedStock.name
            positonStock.nowCost15 = seletedStock.CostLine15
            positonStock.nowCost30 = seletedStock.CostLine30
            positonStock.score = seletedStock.score
            positonStock.Topics = seletedStock.Topics
            positonStock.TopicsHot = seletedStock.TopicsHot
            positonStock.kplTopics = seletedStock.kplTopics
            positonStock.isSelected = 1
            positonStock.defensive15 = seletedStock.CostLine30
            positonStock.defensive30 = defensive
        else:
            return {'code': 0, 'message': "未查询到该股票", 'data': {}}

    # try:
    db.session.add(positonStock)
    db.session.commit()
    return {'code': 1, 'message': "添加成功", 'data': {}}
    # except:
    #     db.session.rollback()
    #     return {'code': 0, 'message': "添加失败", 'data': {}}

# 删除持仓股票
@position.route('/remove/<code>')
def remove(code):
    if len(code) != 6:
        return {'code': 0, 'message': "参数不对"}
    positionStock = PositonStock.query.filter(PositonStock.code == code).first()
    if position is None:
        return {'code': 0, 'message': "未找到该股票"}

    db.session.delete(positionStock)
    db.session.commit()
    return {'code': 1, 'message': "删除成功", 'data': {}}

# 获取持仓股票
@position.route('/allstocks')
def getallstocks():
    stocks = PositonStock.query.all()
    us = PositonStockSchema()
    stock_dic = us.dump(stocks, many=True)
    return {'code': 1, 'messge': '获取持仓股票成功', 'data': stock_dic}

# 获取跌破防守线1股票
@position.route('/fall15')
def getfall15():
    stocks = PositonStock.query.filter(PositonStock.todayIsFall15 == 1).order_by(
        PositonStock.defensive15Time.desc()).all()
    us = PositonStockSchema()
    stock_dic = us.dump(stocks, many=True)
    return {'code': 1, 'messge': '获取跌破防守线1的持仓股票成功', 'data': stock_dic}


# 获取跌破防守线2股票
@position.route('/fall30')
def getfall30():
    stocks = PositonStock.query.filter(PositonStock.todayIsFall30 == 1).order_by(
        PositonStock.defensive30Time.desc()).all()
    us = PositonStockSchema()
    stock_dic = us.dump(stocks, many=True)
    return {'code': 1, 'messge': '获取跌破防守线2的持仓股票成功', 'data': stock_dic}

@position.route('/update')
def upadte_position_stocks():
    with scheduler.app.app_context():
        stocks = PositonStock.query.all()
        for stock in stocks:
            stock.todayIsFall15 = 0
            stock.todayIsFall30 = 0
        db.session.commit()
    return {'code': 1, 'messge': '更新持仓股票成功', 'data': {}}
def montior_stock_list():
    stocks = PositonStock.query.all()
    # 创建一个线程池
    with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
        future_to_thread = [executor.submit(task_handle_montior_stock, stock) for stock in
                            stocks]
        # 等待所有线程完成
        concurrent.futures.wait(future_to_thread)
    return {'code': 1, 'messge': '成功'}

# 监控任务
def task_handle_montior_stock(stock):
    with scheduler.app.app_context():
        data = kpl_tool.get_kpl_real_data(stock.Code)
        positon_stock = PositonStock.query.filter_by(Code=stock.Code).first()
        if data['errcode'] == '0':
            last_px = data['real']['last_px']
            low_px = data['real']['low_px']
            if positon_stock.defensive15 > 0 and positon_stock.todayIsFall15 == 0:
                if positon_stock.defensive15 > last_px or positon_stock.nowCost15 > low_px:
                    positon_stock.defensive15Time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                    positon_stock.isFall15 = 1
                    positon_stock.todayIsFall15 = 1

                    content = '股票' + positon_stock.name + positon_stock.code + '跌破成本线'
                    notice_tool.send_push_copy_message(content, copy=stock.Code, sound='gotosleep')
            if positon_stock.defensive30 > 0 and positon_stock.todayIsFall30 == 0:
                if positon_stock.defensive30 > last_px or positon_stock.defensive30 > low_px:
                    positon_stock.defensive30Time = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
                    positon_stock.isFall30 = 1
                    positon_stock.todayIsFall30 = 1

                    content = '股票' + positon_stock.name + positon_stock.code + '跌破成本线'
                    notice_tool.send_push_copy_message(content, copy=stock.Code, sound='gotosleep')
            db.session.commit()